package GUI;

import DAO.ProductDAO;
import DAO.ProductcatDAO;
import DAO.StoreDAO;
import DAO.UnitDAO;
import GUI.Components.IToolbarPerformEvent;
import GUI.Components.JErrorProvider;
import GUI.Components.ToolbarEvent;
import POJO.Product;
import POJO.Productcat;
import POJO.Store;
import POJO.Unit;
import Util.DataAccessUtil;
import Util.GuiUtil;
import Util.MsgUtil;
import java.awt.event.ItemEvent;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JInternalFrame;
import javax.swing.table.AbstractTableModel;
import org.apache.log4j.Logger;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


/**
 *
 * @author Nguyễn Thi Mỷ Diện (1140214)
 */
public  class FrmProduct extends JInternalFrame {
    private JErrorProvider jErrorControl;
    private Logger log = Logger.getLogger(this.getClass().getName());
    private Store myStore = null;
    public FrmProduct() {
        initComponents();
        // Format input
        GuiUtil.formatDoubleInput(txtUnitprice);
        jErrorControl = new JErrorProvider();
        
        tbProduct.setModel(new ProductModelTable(new ArrayList()));
        this.loadForm();
        this.userControlForm();
    }
    
    private void loadForm(){
          int storeId = 1; // Store id of customer login now
          List<Productcat> listProductcats;
          List<Unit> listUnits;
          try {
            // show name store
             myStore = StoreDAO.getStore(storeId);
             txtStoreName.setText(myStore.getName());
            // show productcats
            listProductcats = ProductcatDAO.getListProductCats(storeId);
            GuiUtil.addListCombobox(cboProductCat,listProductcats,"getName");
            // show unit
            listUnits = UnitDAO.getListUnits();
            GuiUtil.addListCombobox(cboUnit,listUnits,"getName");
            
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex.fillInStackTrace());
        }
    }
    private void cleanControls(){
        txtProductName.setText("");
        txtProductId.setText("");
        txtUnitprice.setValue(0);
    }
    private void setStateControls(boolean editing){
        txtProductName.setEditable(editing);
        txtProductId.setEditable(editing);
        txtUnitprice.setEditable(editing);
        cboUnit.setEnabled(editing);
        cboProductCat.setEnabled(!editing);
        tbProduct.setEnabled(!editing);
    }
    private ProductModelTable getProductModelTable(){
        return (ProductModelTable) tbProduct.getModel();
    }
    private void loadTableProduct(Productcat productcat){
        cleanControls();
        try {
            List<Product> listProducts = ProductDAO.getListProducts(productcat.getId());
            getProductModelTable().setList(listProducts);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex.fillInStackTrace());
        }
    }
    
    private void userControlForm(){
        toolbarProduct.addEventPerformClick(new IToolbarPerformEvent() {
            @Override
            public void performEventAdd(ToolbarEvent evt) {
                cleanControls();
                setStateControls(true);
                cboProductCat.setEnabled(true);
            }

            @Override
            public void performEventEdit(ToolbarEvent evt) {
                if(tbProduct.getSelectedRowCount() < 1){
                    MsgUtil.error("Bạn chưa chọn sản phẩm để sửa!");
                    evt.setIsError(true);
                    return;
                }
                setStateControls(true);
                txtProductId.setEditable(false);
                cboProductCat.setEnabled(false);
            }

            @Override
            public void performEventDelete(ToolbarEvent evt) {
                if(tbProduct.getSelectedRowCount() < 1){
                   MsgUtil.error("Bạn chưa chọn sản phẩm để xóa!");
                   return;
                }
              Product p =  getProductModelTable().getItem(tbProduct.getSelectedRow());
                try {
                    DataAccessUtil.delete(p);
                    MsgUtil.info("Xóa thành công!");
                    loadTableProduct(p.getProductcat());
                } catch (Exception e) {
                    log.error(e.getMessage(),e.fillInStackTrace());
                    MsgUtil.error("Có lỗi trong quá trình xóa!",e.getMessage());
                }
            }

            @Override
            public void performEventSave(ToolbarEvent evt) {
                jErrorControl.clear();
                int numError = 0;
                try {
                    txtUnitprice.commitEdit();
                } catch (ParseException ex) {
                    log.error(ex.getMessage(),ex.fillInStackTrace());
                    numError++;
                }
                if(cboProductCat.getSelectedItem() == null){
                    jErrorControl.setError(cboProductCat, "Chưa có loại sản phẩm!");
                    numError++;
                }
                if(txtProductId.getText().isEmpty()){
                    jErrorControl.setError(txtProductId, "Bạn chưa nhập mã sản phẩm!");
                    numError++;
                }else if(evt.isIsAdding()){
                    try {
                        if(ProductDAO.checkExistsProduct(txtProductId.getText())){
                             jErrorControl.setError(txtProductId, "Mã sản phẩm đã tồn tại!");
                              numError++;
                        }
                    } catch (Exception ex) {
                        log.error(ex.getMessage(),ex.fillInStackTrace());
                         numError++;
                    }
                }
                if(txtProductName.getText().isEmpty()){
                    jErrorControl.setError(txtProductName, "Bạn chưa nhập tên sản phẩm!");
                    numError++;
                }
                if(txtUnitprice.getText().isEmpty()){
                   jErrorControl.setError(txtUnitprice, "Bạn chưa nhập giá sản phẩm!");
                    numError++;
                }
                if(numError > 0){
                    evt.setIsError(true);
                    return;
                }
                
                Productcat c = (Productcat) cboProductCat.getSelectedItem();
                Unit u = (Unit) cboUnit.getSelectedItem();
                Product p;
                if(evt.isIsAdding()){
                    p = new Product();
                    p.setId(txtProductId.getText());
                    p.setProductcat(c);
                    p.setStore(myStore);
                    p.setTotalinstock(0);
                    p.setQuantity(0);
                }else{
                    p = getProductModelTable().getItem(tbProduct.getSelectedRow());
                }
                p.setName(txtProductName.getText());
                p.setUnit(u);
                p.setUnitprice(Float.valueOf(txtUnitprice.getValue().toString()));
                if(evt.isIsAdding()){
                    try {
                       DataAccessUtil.insert(p);
                       MsgUtil.info("Thêm sản phẩm "+p.getName()+" thành công!");
                       loadTableProduct(c);
                    } catch (Exception e) {
                        log.error(e.getMessage(),e.fillInStackTrace());
                        MsgUtil.error("Có lỗi trong quá trình thêm",e.getMessage());
                    }
                }else if(evt.isIsUpdating()){
                    try {
                       DataAccessUtil.update(p);
                       MsgUtil.info("Sửa sản phẩm "+p.getName()+" thành công!");
                       loadTableProduct(c);
                    } catch (Exception e) {
                        log.error(e.getMessage(),e.fillInStackTrace());
                        MsgUtil.error("Có lỗi trong quá trình sửa",e.getMessage());
                    }
                }
                setStateControls(false);
                cleanControls();
            }

            @Override
            public void performEventCancel(ToolbarEvent evt) {
                 setStateControls(false);
                 jErrorControl.clear();
                 if(cboProductCat.getSelectedItem() != null)
                     loadTableProduct((Productcat)cboProductCat.getSelectedItem());
            }

            @Override
            public void performEventRefresh(ToolbarEvent evt) {
            }

            @Override
            public void performEventClose(ToolbarEvent evt) {
                dispose();
            }

     
        });
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        tbProduct = new javax.swing.JTable();
        jPanel1 = new javax.swing.JPanel();
        txtProductName = new javax.swing.JTextField();
        jLabel8 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        cboUnit = new javax.swing.JComboBox();
        txtProductId = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        cboProductCat = new javax.swing.JComboBox();
        jLabel1 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        txtUnitprice = new javax.swing.JFormattedTextField();
        txtStoreName = new javax.swing.JTextField();
        toolbarProduct = new GUI.Components.Toolbar();

        setTitle("Sản phẩm");
        setVisible(true);

        tbProduct.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Mã sản phẩm", "Tên sản phẩm", "Đơn giá", "Số lượng", "Số lượng tồn"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.Double.class, java.lang.Integer.class, java.lang.Integer.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        tbProduct.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tbProductMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(tbProduct);

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Thông tin sản phẩm", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 12))); // NOI18N

        txtProductName.setEditable(false);
        txtProductName.setName("jTextField_idSanPham");

        jLabel8.setText("Đơn vị tính:");

        jLabel2.setText("Tên sản phẩm:");

        cboUnit.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        cboUnit.setEnabled(false);
        cboUnit.setName("");

        txtProductId.setEditable(false);
        txtProductId.setName("jTextField_TenSanPham");

        jLabel3.setText("Đơn giá:");

        cboProductCat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        cboProductCat.setName("");
        cboProductCat.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cboProductCatItemStateChanged(evt);
            }
        });

        jLabel1.setText("Mã sản phẩm:");

        jLabel5.setText("Danh mục:");

        jLabel7.setText("Cửa hàng:");

        txtUnitprice.setEditable(false);
        txtUnitprice.setFocusLostBehavior(javax.swing.JFormattedTextField.COMMIT);

        txtStoreName.setEditable(false);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel5)
                            .addComponent(jLabel3))
                        .addGap(14, 14, 14))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)))
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(txtProductId)
                    .addComponent(txtProductName)
                    .addComponent(cboProductCat, 0, 207, Short.MAX_VALUE)
                    .addComponent(txtUnitprice))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 75, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel7)
                    .addComponent(jLabel8))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(txtStoreName, javax.swing.GroupLayout.PREFERRED_SIZE, 212, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cboUnit, javax.swing.GroupLayout.PREFERRED_SIZE, 139, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(25, 25, 25))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel8)
                    .addComponent(cboProductCat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(cboUnit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtProductId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(txtStoreName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtProductName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtUnitprice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addGap(19, 19, 19))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jScrollPane1)
            .addGroup(layout.createSequentialGroup()
                .addComponent(toolbarProduct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(toolbarProduct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 353, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void tbProductMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tbProductMouseClicked
       Product product = getProductModelTable().getItem(tbProduct.getSelectedRow());
       txtProductId.setText(product.getId());
       txtProductName.setText(product.getName());
       txtUnitprice.setValue(product.getUnitprice());
        // select cbo unit
       GuiUtil.selectComboboxItem(cboUnit, product.getUnit().getId(), "getId");
       
    }//GEN-LAST:event_tbProductMouseClicked

    private void cboProductCatItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboProductCatItemStateChanged
        if(evt.getStateChange() == ItemEvent.SELECTED){
            this.loadTableProduct((Productcat)evt.getItem());
        }
    }//GEN-LAST:event_cboProductCatItemStateChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox cboProductCat;
    private javax.swing.JComboBox cboUnit;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable tbProduct;
    private GUI.Components.Toolbar toolbarProduct;
    private javax.swing.JTextField txtProductId;
    private javax.swing.JTextField txtProductName;
    private javax.swing.JTextField txtStoreName;
    private javax.swing.JFormattedTextField txtUnitprice;
    // End of variables declaration//GEN-END:variables

}

//<editor-fold defaultstate="collapsed" desc="Product model table">
class ProductModelTable extends AbstractTableModel {

    private static final String[] columnNames = {"Mã sản phẩm", "Tên sản phẩm", "Đơn giá",
                                                "Số lượng", "Số lượng tồn"};
    private List<Product> list;

    public ProductModelTable(List<Product> list) {
        this.list = list;
    }

    public List<Product> getList() {
        return this.list;
    }
    public Product getItem(int rowIndex){
        return this.list.get(rowIndex);
    }
    public void setList(List<Product> list) {
        this.list = list;
        fireTableDataChanged();
    }

    public void removeAllElement() {
        this.list.clear();
        fireTableDataChanged();
    }

    public void addElement(Product e) {
        // Adds the element in the last position in the list
        list.add(e);
        fireTableRowsInserted(list.size() - 1, list.size() - 1);
    }

    public void removeElement(int rowIndex) {
        list.remove(rowIndex);
        fireTableRowsDeleted(rowIndex, rowIndex);
    }

    @Override
    public int getRowCount() {
        return list.size();
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public String getColumnName(int index) {
        return columnNames[index];
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch (columnIndex) {
            case 0:
                return list.get(rowIndex).getId();
            case 1:
                return list.get(rowIndex).getName();
            case 2:
                return list.get(rowIndex).getUnitprice();
            case 3:
                return list.get(rowIndex).getTotalinstock();
            case 4:
                return list.get(rowIndex).getQuantity();
        }
        return null;
    }
}
//</editor-fold>
